//c调用p时首先根据当前
//p跟
#include "htsc_grpc_trace.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "grpc/support/tls.h"
#include "grpc/support/thd.h"
#include "grpc/support/alloc.h"

#include "htsc_common/htsc_grpc_properties_tools.h"
#include "htsc_grpc_conf.h"
#include "htsc_grpc_utils.h"

//是否生成服务链标记 
// -1 未初始化 1 需要生成服务链 0 不需要生成服务链
static int htsc_grpc_trace_gentrace_flag = -1;
static int htsc_grpc_trace_threadlocal_isinit = -1;


//------------------start deal  consumer threadlocal traceinfo------------------
GPR_TLS_DECL(hstc_grpc_trace_threadlocal);

//初始化threadlocal对象
void htsc_grpc_trace_threadlocal_init() {
	if (htsc_grpc_trace_threadlocal_isinit != 1) {
		gpr_tls_init(&hstc_grpc_trace_threadlocal);
		htsc_grpc_trace_threadlocal_isinit = 1;
	}
}

void htsc_grpc_trace_threadlocal_enter(hstc_grpc_trace_threadlocal_t *traceinfo) {
	//GPR_ASSERT(gpr_tls_get(&htsc_grpc_consumer_traceinfo) == 0);
	gpr_tls_set(&hstc_grpc_trace_threadlocal, (intptr_t)traceinfo);
}

//清除threadlocal对象
void htsc_grpc_trace_threadlocal_clear_bk(hstc_grpc_trace_threadlocal_t *traceinfo) {
	intptr_t pt = gpr_tls_get(&hstc_grpc_trace_threadlocal);
	intptr_t pn = (intptr_t)traceinfo;
	//校验threadlocal是否一致
	//GPR_ASSERT(gpr_tls_get(&htsc_grpc_consumer_traceinfo) == (intptr_t)traceinfo);
	if (pt > 0) {	  
		hstc_grpc_trace_threadlocal_t *c = (hstc_grpc_trace_threadlocal_t *)gpr_tls_get(&hstc_grpc_trace_threadlocal);
		/*int thd_id = (int)GetCurrentThreadId();
		if (thd_id == c->consumertrace->callcount) {
			printf("\n-------------threadlocal is ok: %d ", c->consumertrace->callcount);
	    } else {
			printf("\n-------------thread id is not same.... %s","!!!!");
		}*/
	}
	/* else {
		printf("\n-------------thread local is null...... %s","!!!!");
	}*/
	gpr_tls_set(&hstc_grpc_trace_threadlocal, 0);
}

//清除threadlocal对象
void htsc_grpc_trace_threadlocal_clear() {
	intptr_t pt = gpr_tls_get(&hstc_grpc_trace_threadlocal);
	//校验threadlocal是否一致
	//GPR_ASSERT(gpr_tls_get(&htsc_grpc_consumer_traceinfo) == (intptr_t)traceinfo);
	//if (pt > 0) {
	//	int thd_id = (int)GetCurrentThreadId();
	//	hstc_grpc_trace_threadlocal_t *c = (hstc_grpc_trace_threadlocal_t *)gpr_tls_get(&hstc_grpc_trace_threadlocal);
	//	if (thd_id == c->consumertrace->callcount) {
	//		//printf("\n-------------threadlocal is ok: %d ", c->consumertrace->callcount);
	//	}
	//	else {
	//		printf("\n-------------thread id is not same.... %s", "!!!!");
	//	}
	//}
	//else {
	//	printf("\n-------------thread local is null...... %s", "!!!!");
	//}
	if (pt > 0) {
		gpr_tls_set(&hstc_grpc_trace_threadlocal, 0);
	}
}

//获取当前存放的threadlocal信息
hstc_grpc_trace_threadlocal_t *htsc_grpc_trace_threadlocal_getcurrenttrace() {
	intptr_t tthreadlocal = gpr_tls_get(&hstc_grpc_trace_threadlocal);
	if (tthreadlocal <= 0) {
		return NULL;
	}
	return (hstc_grpc_trace_threadlocal_t *)tthreadlocal;
}

/*
* 是否trace结构体信息
* 注意：有部分属性是不需要释放的指针直接置空就可以了
*/
void htsc_grpc_trace_free(hstc_grpc_common_traceinfo_t **traceinfo) {
	hstc_grpc_common_traceinfo_t *ptrace = *traceinfo;
	//FREE_PTR(ptrace->traceid);	
	//FREE_PTR(ptrace->parentchainid);  //上级节点chainid
 
	/**
	* 监控消息/服务链
	* 服务名，仅支持-_.少数符号.
	*/
	FREE_PTR(ptrace->servicename);

	/**
	* 方法名， 仅支持-_.$少数符号.
	*/
	FREE_PTR(ptrace->methodname);

	/**
	* 服务调用开始时间.
	*/
	//FREE_PTR(ptrace->starttime);

	/**
	* 服务调用结束时间.
	*/
	//FREE_PTR(ptrace->endtime); 

	/**
	* 服务消费方ip.
	*/
	//FREE_PTR(ptrace->consumerhost);

	/**
	* 服务消费方端口.
	*/
	//FREE_PTR(ptrace->consumerport);

	/**
	* 服务提供方ip.
	*/
	//FREE_PTR(ptrace->providerhost);

	/**
	* 服务提供方端口.
	*/
	//FREE_PTR(ptrace->providerport);

	/**
	* 服务协议，dubbo、rest等.
	*/
	//FREE_PTR(ptrace->protocol);   //常量不需要释放该指针

	/**
	* 服务分组， 仅支持-_.少数符号.
	*/
	//FREE_PTR(ptrace->servicegroup); 
	ptrace->servicegroup = NULL;
	ptrace->serviceversion = NULL;  //不需要释放该指针
	ptrace->appname = NULL;         //不需要释放该指针
	FREE_PTR(ptrace);
}


//是否进行服务跟踪 
//1 需要进行服务跟踪 
//0 不进行服务跟踪
int htsc_grpc_trace_info_istrace() {
	//参数为初始化
	if (htsc_grpc_trace_gentrace_flag == -1) {
		//读取配置文件
		size_t buffsize = sizeof(char) * 100;
		char *paramconf = (char*)gpr_malloc(buffsize);
		memset(paramconf, 0, buffsize);
		htsc_grpc_properties_get_value(HTSC_GRPC_TRACE_GENTRACE_KEY, NULL, paramconf);
		if (paramconf == NULL || strcmp(paramconf, "") == 0 || strcmp(paramconf, "true") == 0) {
			htsc_grpc_trace_gentrace_flag = HTSC_GRPC_TRACE_GENTRACE_Y;
		} else {
			htsc_grpc_trace_gentrace_flag = HTSC_GRPC_TRACE_GENTRACE_N;
		}
	} 
	return htsc_grpc_trace_gentrace_flag;
}

//把trace信息写入队列
//暂时未使用
int htsc_grpc_trace_write_queue(hstc_grpc_common_traceinfo_t *traceinfo) {
	return 0;
}

char * htsc_grpc_trace_protocol_get() {
	return "grpc";
}


